\chapter{开始使用Geant4---从运行简单例子开始}
\thispagestyle{empty}

\section{如何定义main程序}
\subsection{一个简单的main程序}
main函数的内容会根据给定的模拟应用程序的需要而变化，因此必须由用户提供。 GEANT4工具包没有提供main方法，但是这里提供了一个样本作为初始用户的指南。 清单2.1是构建仿真程序所需的main函数的最简单示例\footnote{translate by九九之九}。
%\begin{tcblisting}{colback=red!5,colframe=red!75!black}
%This is a \LaTeX\ example:
%$\displaystyle\sum\limits_{i=1}^n i = \frac{n(n+1)}{2}$.
%\end{tcblisting}

%title=nihao,

\begin{lstlisting}[caption= main函数最简单的例子]
#include "G4RunManager.hh"
#include "G4UImanager.hh"
#include "ExG4DetectorConstruction01.hh"
#include "ExG4PhysicsList00.hh"
#include "ExG4ActionInitialization01.hh"
int main()
{
	// construct the default run manager
	G4RunManager* runManager = new G4RunManager;
	// set mandatory initialization classes
	runManager->SetUserInitialization(new ExG4DetectorConstruction01);
	runManager->SetUserInitialization(new ExG4PhysicsList00);
	runManager->SetUserInitialization(new ExG4ActionInitialization01);
	// initialize G4 kernel
	runManager->Initialize();
	// get the pointer to the UI manager and set verbosities
	G4UImanager* UI = G4UImanager::GetUIpointer();
	UI->ApplyCommand("/run/verbose 1");
	UI->ApplyCommand("/event/verbose 1");
	UI->ApplyCommand("/tracking/verbose 1");
	// start a run int numberOfEvent = 3;
	runManager->BeamOn(numberOfEvent);
	// job termination
	delete runManager;
	return 0;
}
\end{lstlisting}


%\begin{tcblisting}
%#include <iostream>
%using namespace std;
%int main()
%{
%    cout<<"hello"<<endl;
%    return 0;
%}
%\end{tcblisting}


%\begin{minted}{C++}{main}
%#include <iostream>
%using namespace std;
%
%int main()
%{
%    cout<<"hello"<<endl;
%    return 0;
%}
%\end{minted}

main方法由两个工具箱类G4RunManager和G4UImanager以及从工具包类派生的三个类ExG4DetectorConstruction01，ExG4PhysicsList00和ExG4ActionInitialization01实现。 以下各节将对每种解决方案进行说明。

\subsection{G4RunManager }
main（）必须做的第一件事是创建一个G4RunManager类的实例。 这是GEANT4内核中唯一应该在用户的main（）中显式构造的管理器类。 它控制程序的流程并在运行中管理事件循环。 如果用户想要使仿真代码为多线程，则应该实例化G4MTRunManager而不是G4RunManager。
当创建G4RunManager时，还会创建其他主要管理器类。 当G4RunManager被删除时它们被自动删除。 运行管理器还负责管理初始化过程，包括用户初始化类中的方法。 通过这些，运行经理必须获得构建和运行仿真所需的全部信息，其中包括
\begin{enumerate}
  \item how the detector should be constructed, 如何构造探测器，
  \item all the particles and all the physics processes to be simulated, 所有的粒子和所有物理过程都要模拟，
  \item how the primary particle(s) in an event should be produced, 应该如何产生事件中的主要粒子
  \item 要模拟的其他附加要求
\end{enumerate}

 在main（）的示例中
\begin{lstlisting}[ numbers=none]
runManager->SetUserInitialization(new ExG4DetectorConstruction01);
runManager->SetUserInitialization(new ExG4PhysicsList00);
runManager->SetUserInitialization(new ExG4ActionInitialization01);
\end{lstlisting}
创建分别指定探测器几何体，物理过程和主要粒子的对象，并将其指针传递给运行管理器。

\subsubsection{ExG4DetectorConstruction01}

 ExG4DetectorConstruction01是从G4VUserDetectorConstruction派生的用户初始化类的示例。 这是用户描述整个检测器设置的地方，包括
\begin{itemize}
  \item its geometry, 几何形状
  \item the materials used in its construction建模中使用的材料
  \item a definition of its sensitive regions and 其敏感区域的定义
  \item the readout schemes of the sensitive regions敏感区域的读出方案.
\end{itemize}

\subsubsection{ExG4PhysicsList01}

同样，ExG4PhysicsList01从G4VUserPhysicsList派生，并要求用户定义
\begin{itemize}
  \item the particles to be used in the simulation要在模拟中使用的粒子，
  \item all the physics processes to be simulated所有要模拟的物理过程.
  \end{itemize}
User can also override the default implementation for用户也可以覆盖默认实现
\begin{itemize}

  \item the range cuts for these particles and这些粒子的范围削减

\end{itemize}

\subsubsection{ExG4ActionInitialization01}

另外ExG4ActionInitialization01从G4VUserActionInitialization派生，并要求用户定义
\begin{itemize}
\item so-called user action classes (see next section) that are invoked during the simulation, 在仿真过程中调用的所谓用户操作类（参见下一节）
\item which includes one mandatory user action to define the primary particles.
\end{itemize}

The next instruction其中包括一个用于定义主要粒子的强制用户操作。下一条指令执行检测器构造，创建物理过程，计算横截面并以其他方式设置运行。 main（）中的最终运行管理器方法

\begin{lstlisting}[ numbers=none]
runManager->Initialize();
int numberOfEvent = 3;
runManager->beamOn(numberOfEvent);
\end{lstlisting}

开始连续处理三个事件。 可以在main（）中调用任何次数的beamOn（）方法，每个调用代表一次单独的运行。 一旦开始运行，检测器设置和物理过程都不能改变。 但是，它们可能会在运行之间更改，如定制运行管理器中所述。 有关G4RunManager的更多信息，请参阅Run。

如上所述，创建运行管理器时会创建其他管理器类。 其中之一是用户界面管理器G4UImanager。 在main（）中必须获得一个指向接口管理器的指针

\begin{lstlisting}[ numbers=none]
G4UImanager* UI = G4UImanager::getUIpointer();
\end{lstlisting}

以便用户向程序发出命令。 在本例中，调用applyCommand（）方法三次，以指示程序在模拟的运行，事件和跟踪级别打印信息。 有多种命令可供用户对模拟进行详细控制。 这些命令的列表可以在Built-in Commands. 中找到。
\subsection{User Initialization and Action Classes【用户初始化和操作类】}

\subsubsection{User Classes【用户类】}
有两种用户类，用户初始化类和用户操作类。 初始化阶段使用用户初始化类，而运行期间使用用户操作类。 用户初始化类应通过SetUserInitialization（）方法直接设置为G4RunManager，而用户操作类应在G4VUserActionInitialization类中定义
\subsubsection{User Initialization Classes【用户初始化类】}
所有三个用户初始化类都是必需的。 它们必须来自GEANT4提供的抽象基类:
\begin{itemize}
  \item G4VUserDetectorConstruction
  \item G4VUserPhysicsList
  \item G4VUserActionInitialization
\end{itemize}

GEANT4不为这些类提供默认行为。 当调用Initialize（）和BeamOn（）方法时，G4RunManager检查这些强制类的存在

如前一节所述，G4VUserDetectorConstruction要求用户定义探测器，并且G4VUserPhysicsList要求用户定义物理。 检测器定义将在“如何定义检测器几何以及如何在检测器中指定材料”部分中讨论。 物理定义将在如何指定粒子和如何指定物理过程中讨论。 用户操作G4VUserPrimaryGeneratorAction要求定义初始事件状态。 主要事件的产生将在如何制作可执行程序中讨论。

G4VuserActionInitialization应包括至少一个强制用户操作类 G4VUserPrimaryGeneratorAction. 下一节将介绍所有用户操作类。

\begin{lstlisting}[caption= ExG4ActionInitialization01最简单的例子]
#include "ExG4ActionInitialization01.hh"
#include "ExG4PrimaryGeneratorAction01.hh"
void ExG4ActionInitialization01::Build() const
{
    SetUserAction(new ExG4PrimaryGeneratorAction01);
}
\end{lstlisting}


\subsubsection{User Action Classes【用户操作类】}
G4VUserPrimaryGeneratorAction是用户必须提供的强制类。 它创建一个主要粒子生成器的实例。 ExG4PrimaryGeneratorAction01是从G4VUserPrimaryGeneratorAction派生的用户操作类的示例。 在这个类中，用户必须描述主事件的初始状态。 这个类有一个名为GeneratePrimaries（）的公共虚拟方法，它将在每个事件的开始时被调用。 详细信息将在如何生成主事件中给出。 请注意，GEANT4不提供用于生成主事件的任何默认行为。

GEANT4 provides additional five user hook classes ： GEANT4提供额外的五个用户钩子类:
\begin{itemize}
  \item G4UserRunAction
  \item G4UserEventAction
  \item G4UserStackingAction
  \item G4UserTrackingAction
  \item G4UserSteppingAction
\end{itemize}

这些可选的用户操作类具有多种虚拟方法，允许在仿真应用程序的各个级别指定附加程序。 用户操作中提供了用户初始化和操作类的详细信息。

\subsection{G4UImanager and UI CommandSubmission命令提交}GEANT4提供了一个名为intercoms的类别。 G4UImanager是这个类别的manager类。 使用这个类别的功能，你可以调用你不知道指针的类对象的set方法。 在清单2.3中，设置了各种GEANT4管理器类的详细信息。 对话的详细机制描述和使用将在下一章给出，并提供可用命令的列表。 命令提交可以通过应用程序完成
\begin{lstlisting}[caption= ExG4ActionInitialization01最简单的例子]
#include "G4RunManager.hh"
#include "G4UImanager.hh"
#ifdef G4UI_USE
#include "G4VisExecutive.hh"
#endif
#include "ExG4DetectorConstruction01.hh"
#include "ExG4PhysicsList00.hh"
#include "ExG4PrimaryGeneratorAction01.hh"
int main()
{
	// construct the default run manager
	G4RunManager* runManager = new G4RunManager;
	// set mandatory initialization classes
	runManager->SetUserInitialization(new ExG4DetectorConstruction01);
	runManager->SetUserInitialization(new ExG4PhysicsList00);
	// set mandatory user action class
	runManager->SetUserAction(new ExG4PrimaryGeneratorAction01);
	// initialize G4 kernel
	runManager->Initialize();
	// Get the pointer to the User Interface manager
	G4UImanager* UImanager = G4UImanager::GetUIpointer();
	if ( argc == 1 ) {
		// interactive mode : define UI session
#ifdef G4UI_USE
		G4UIExecutive* ui = new G4UIExecutive(argc, argv); UImanager->ApplyCommand("/control/execute init.mac");
		ui->SessionStart();
		delete ui;
#endif
	}
	else {
		// batch mode
		G4String command = "/control/execute ";
		G4String fileName = argv[1];
		UImanager->ApplyCommand(command+fileName);
	}
	// job termination
	delete runManager;
	return 0;
}
\end{lstlisting}
\subsection{G4cout and G4cerr}
尽管尚未包含在上述示例中，但仍需要输出流。 G4cout和G4cerr是由GEANT4定义的iostream对象。 除了输出流将由G4UImanager处理外，这些对象的用法与普通cout和cerr完全相同。 因此，输出字符串可能会显示在另一个窗口中或存储在文件中。 这些输出流的操作将在如何控制G4cout / G4cerr的输出中介绍。 应该使用这些对象来代替普通的cout和cerr。

\section{How to Define a Detector Geometry【如何定义探测器几何】}
\subsection{Basic Concepts【基本概念】}
GEANT4中的探测器几何体由多个体积【Volumes】组成。最大的体被称为世界体【World Volume】。它必须包含检测器几何体中的所有其他体。其他Volume创建并放置在以前的Volume中，包含在世界Volume中。描述世界的最简单（和高效）的形状是一个box {translate by九九之九}。

每个Volume都是通过描述其形状和物理特征而创建的，然后将其放置包含在Volume中。


当一个Volume被放入另一个Volume时，我们称前Volume为子体【daughter Volume】，后者为母体【mother Volume】。用于指定子Volume的放置位置的坐标系是母Volume的坐标系。


为了描述一个体积的形状，我们使用一个实体【solid】的概念。实体是一个几何对象，它具有每个形状尺寸的形状和特定值。一个边长10厘米，半径30厘米，长75厘米的圆柱体是实体的例子。

要描述Volume的完整属性，我们使用逻辑体【logical volume】。它包括实体solid的几何特性，并增加物理特性：体积的材料;是否包含任何敏感的探测器元件;磁场;等等。

我们尚未描述如何放置Volume。为此，您可以创建一个物理体【physical volume】，将逻辑体的副本放入一个更大的包含Volume中。


\subsection{Create a Simple Volume【创建一个简单的Volume】}
What do you need to do to create a volume?
\begin{itemize}
  \item Create a solid. 创建一个实体
  \item Create a logical volume, using this solid, and adding other attributes. 使用此实体创建逻辑体，并添加其他属性
\end{itemize}

每种volume类型（solid, logical, and physical）都有一个关联的注册表（VolumeStore），其中包含到目前为止构建的所有类型对象的列表。 注册管理机构将在请求时自动删除这些对象; 用户不应手动删除几何对象。

\subsection{Choose a Solid【选择一个实体】}

要创建一个简单的box，您只需要沿每个笛卡尔坐标轴【Cartesian axes】定义其名称和范围.
\begin{lstlisting}[caption= Creating a box]
G4double world_hx = 3.0*m;
G4double world_hy = 1.0*m;
G4double world_hz = 1.0*m;
G4Box* worldBox
= new G4Box("World", world_hx, world_hy, world_hz);
\end{lstlisting}
这将创建一个名为“World”的box，其范围X轴为-3.0米到+3.0米，Y轴从-1.0到1.0米，Z从-1.0到1.0米。请注意，G4Box构造函数是box长度的半长。
创建圆柱体也非常简单。 为此，您可以使用G4Tubs类



\begin{lstlisting}[caption= Creating a cylinder创建一个圆柱体]
G4double innerRadius = 0.*cm;
G4double outerRadius = 60.*cm;
G4double hz = 25.*cm;
G4double startAngle = 0.*deg;
G4double spanningAngle = 360.*deg;
G4Tubs* trackerTube
= new G4Tubs("Tracker",
		innerRadius,
		outerRadius,
		hz,
		startAngle, spanningAngle);
\end{lstlisting}

这将创建一个半径为60厘米，长度为50厘米的完整圆柱体，称为“跟踪器【Tracker】”（hz参数表示Z轴的一半长度）

\subsection{Create a Logical Volume【创建一个逻辑Volume】}
要创建逻辑体，您必须从实体和材质开始。 因此，使用上面创建的盒子，您可以创建一个填充有氩气的简单逻辑体（请参阅如何在检测器中指定材料），方法是输入

\begin{lstlisting}[numbers=none]
G4LogicalVolume* worldLog
     = new G4LogicalVolume(worldBox, Ar, "World");
\end{lstlisting}
这个逻辑volume被命名为“world”。

类似地，我们用填充铝的圆柱形固体创建逻辑volume

\begin{lstlisting}[numbers=none]
G4LogicalVolume* trackerLog
     = new G4LogicalVolume(trackerTube, Al, "Tracker");
\end{lstlisting}
and named “Tracker”.

\subsection{Place a Volume【放置一个volume】}
你如何放置volume？ 您从一个逻辑volume开始，然后决定放置它的内部已经存在的volume。 然后，您决定将该中心放在该volume的哪个位置，以及如何旋转它。 一旦你做出了这些决定，你可以创建一个物理volume，它是volume的放置实例，并体现所有这些属性。.

\subsection{Create a Physical Volume【创建一个物理volume】}
您可以从逻辑体开始创建物理体。 物理体仅仅是逻辑体的放置实例。 此实例必须放置在母逻辑体内。 为了简单起见，它是不旋转的

\begin{lstlisting}[caption= A simple physical volume一个简单的物理量]
G4double pos_x = -1.0*meter;
G4double pos_y = 0.0*meter;
G4double pos_z = 0.0*meter;
G4VPhysicalVolume* trackerPhys
= new G4PVPlacement(0,	// no rotation
		G4ThreeVector(pos_x, pos_y, pos_z),
		// translation position
		trackerLog,	// its logical volume
		"Tracker",	// its name
		worldLog,	// its mother (logical) volume
		false,	// no boolean operations
		0);	// its copy number
\end{lstlisting}
这将把logical volume trackerLog放置在mother volume worldLog的原点，沿X移动一米并且未旋转。 生成的physical volume被命名为“Tracker”，并且其拷贝数【copy number】为0。

物理体必须放置在母volume内，但存在一个例外。 这个例外就是世界volume，它是创建的最大volume，其中包含所有其他volume。 这个世界体显然不能包含在其他任何体中。 相反，它必须创建为具有空母指针的G4PVPlacement。 它也必须是未旋转的，它必须放在全局坐标系的原点。

通常，最好选择一个简单的实体作为World volume，所有基本示例都使用G4Box实体类型。

\subsection{Coordinate Systems and Rotations【坐标系和旋转】}
在GEANT4中，与放置物理体相关联的旋转矩阵表示该体积参考系相对于其母体的旋转。
通常通过实例化单位矩阵，然后对其应用旋转来构建旋转矩阵，如同在CLHEP中那样。 这也在示例B3中得到了证明。


\section{How to Specify Materials in the Detector【如何在检测器中指定材料】}
\subsection{General Considerations【一般注意事项】}
在自然界中，一般材料（化合物，混合物）由元素组成，元素由同位素组成。 因此，这些是GEANT4设计的三大类。 每个类都有一个表作为静态数据成员，用于跟踪各个类创建的实例。 所有三个对象都会自动注册到相应的构造表中，并且不应该在用户代码中删除{translate by九九之九}。

The G4Element class describes the properties of the atoms G4Element类描述了原子的属性：:

\begin{itemize}
 \item atomic number原子数,
 \item number of nucleons核子数量,
 \item atomic mass原子质量,
 \item shell energy壳能,
 \item as well as quantities such as cross sections per atom, etc以及数量，如每个原子的横截面等.
\end{itemize}
The G4Material class describes the macroscopic properties of matter: G4Material类描述了物质的宏观性质
 \begin{itemize}
 \item density, 密度
 \item state, 状态，
 \item temperature, 温度，
 \item pressure, 压力
 \item as well as macroscopic quantities like radiation length, mean free path, dE/dx, etc以及宏观量如辐射长度，平均自由程，dE / dx等.
     \end{itemize}

G4Material类是工具包其余部分可见的类，并且由跟踪，几何和物理学使用。 它包含所有关于它的最终元素和同位素的信息，同时隐藏实施细节.

\subsection{Define a Simple Material【定义一个简单的材料】}
在下面的例子中，通过指定其名称，密度，每摩尔质量和原子序数，创建液态氩.
\begin{lstlisting}[caption=Creating liquid argon创建液态氩.]
G4double z, a, density; density = 1.390*g/cm3; a = 39.95*g/mole;
G4Material* lAr = new G4Material(name="liquidArgon", z=18., a, density);
\end{lstlisting}

指向材质的指针lAr将用于指定给定logical volume的内容：

\begin{lstlisting}[numbers=none]
G4LogicalVolume* myLbox = new G4LogicalVolume(aBox,lAr,"Lbox",0,0,0);
\end{lstlisting}

\subsection{Define a Molecule【定义一个分子】}

在下面的例子中，通过指定分子中的原子数量，水，H2O由其组件构建而成.

\begin{lstlisting}[caption=Creating water by defining its molecular components通过定义其分子组件来创建水]
G4double z, a, density;
G4String name, symbol;
G4int ncomponents, natoms;
a = 1.01*g/mole;
G4Element* elH = new G4Element(name="Hydrogen",symbol="H" , z= 1., a);
a = 16.00*g/mole;
G4Element* elO = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
density = 1.000*g/cm3;
G4Material* H2O = new G4Material(name="Water",density,ncomponents=2);
H2O->AddElement(elH, natoms=2);
H2O->AddElement(elO, natoms=1);
\end{lstlisting}
\subsection{Define a Mixture by Fractional Mass【根据质量分数定义混合物】}
在下面的例子中，空气由氮和氧构成，通过给出每种组分的质量分数.
\begin{lstlisting}[caption=Creating air by defining the fractional mass of its components]
G4double z, a, fractionmass, density;
G4String name, symbol;
G4int ncomponents;
a = 14.01*g/mole;
G4Element* elN = new G4Element(name="Nitrogen",symbol="N" , z= 7., a);
a = 16.00*g/mole;
G4Element* elO = new G4Element(name="Oxygen" ,symbol="O" , z= 8., a);
density = 1.290*mg/cm3; G4Material* Air = new G4Material(name="Air ",density,ncomponents=2);
Air->AddElement(elN, fractionmass=70*perCent);
Air->AddElement(elO, fractionmass=30*perCent);
\end{lstlisting}

\subsection{Define a Material from the GEANT4 Material Database【从G4材料库中定义材料】}
在下面的例子中，通过GEANT4材料数据库访问空气和水。
\begin{lstlisting}[caption=Defining air and water from the internal GEANT4 database]
G4NistManager* man = G4NistManager::Instance();
G4Material* H2O = man->FindOrBuildMaterial("G4_WATER");
G4Material* Air = man->FindOrBuildMaterial("G4_AIR");
\end{lstlisting}
\subsection{Define a Material from the Base Material【从基材定义材料】}
可以在现有“基础【base】”材料的基础上构建新材料。 此功能对于电磁物理学非常有用，可以为所导出的材料确定所有校正数据和基础材料的停止功率和横截面的预先计算表格。 在下面的例子中，显示了两种如何创建密度不同的水的方法.
\begin{lstlisting}[caption=Defining water with user defined density on base of G4\_WATER]
G4double density;
density = 1.05*mg/cm3;
G4Material* water1 = new G4Material("Water_1.05",density,"G4_WATER");
density = 1.03*mg/cm3; G4NistManager* man = G4NistManager::Instance();
G4Material* water2 = man->BuildMaterialWithNewDensity("Water_1.03","G4_WATER",density);
\end{lstlisting}
\subsection{Print Material Information【打印材料信息】}
\begin{lstlisting}[caption=Printing information about materials]
G4cout << H2O;	\\ print a given material
G4cout << *(G4Material::GetMaterialTable()); \\ print the list of materials
\end{lstlisting}
In GEANT4 examples you all possible ways to build a material.

\subsection{Access to GEANT4 material database【访问GEANT4材料数据库】}
\begin{lstlisting}[caption=GEANT4 material database may be accessed via UI commands]
/material/nist/printElement Fe	\\ print element by name
/material/nist/printElementZ 13	 \\ print element by atomic number
/material/nist/listMaterials type \\ print materials type = [simple | compound | hep | all]
/material/g4/printElement elmName  \\ print instantiated element by name
/material/g4/printMaterial matName  \\ print instantiated material by name
\end{lstlisting}
在GEANT4的例子中，您可以找到所有可能的方法来构建材料.

\section{How to Specify Particles【如何指定粒子】}
G4VUserPhysicsList是如何定义main（）程序中描述的强制用户基类之一。 在这个类中，必须定义模拟中要使用的所有粒子和物理过程。 范围截止参数【range cut-of】也应该在这个类中定义.

用户必须创建一个派生自G4VuserPhysicsList的类并实现以下纯虚拟方法:
\begin{lstlisting}[numbers=none]
ConstructParticle();	// construction of particles
ConstructProcess();	// construct processes and register them to particles
\end{lstlisting}
用户可能还想覆盖下面的虚拟方法的默认实现:
\begin{lstlisting}[numbers=none]
SetCuts();	// setting a range cut value for all particles
\end{lstlisting}
本节提供了一些ConstructParticle（）和SetCuts（）方法的简单示例。 有关ConstructProcess（）方法的信息，请参阅如何指定物理过程。
\subsection{Particle Definition【粒子定义】}
GEANT4提供各种类型的粒子用于模拟{translate by九九之九}:

\begin{itemize}
 \item ordinary particles, such as electrons, protons, and gammas普通粒子，如电子，质子和伽玛
 \item 寿命非常短的共振粒子，如矢量介子和三角形重子
 \item nuclei,核，如氘核，α核和重离子（包括超核）
 \item quarks, di-quarks, and gluon夸克，迪夸克和胶子
\end{itemize}

每个粒子都由它自己的类来表示，它是从G4ParticleDefinition派生而来的。 （例外：G4Ions代表所有重核，请参阅粒子。）粒子分为六大类：
\begin{itemize}
\item  lepton轻子,
\item  meson介子,
\item  baryon重子,
\item  boson玻色子,
\item  shortlived 短寿命粒子
\item   ion离子,
\end{itemize}

其中每个都在geant4 / source / particles下的相应子目录中定义。 每个粒子类别还有一个相应的粒度库【particle category】.

\subsubsection{The G4ParticleDefinition Class}

G4ParticleDefinition具有表征单个粒子的属性，例如名称，质量，电荷，旋转等。 大多数这些属性是“只读”的，不能直接更改。

G4ParticlePropertyTable用于从G4ParticlePropertyData中检索（加载） G4ParticleDefinition的particle属性。
\subsubsection{How to Access a Particle【如何访问一个粒子】}
每个粒子类类型代表一个单独的粒子类型，每个类都有一个单独的对象。 这个对象可以通过使用每个类的静态方法来访问。 这条规则有一些例外; 详情请参阅粒子。

例如，G4Electron类代表电子，成员G4Electron :: theInstance指向其唯一对象。 指向此对象的指针可通过静态方法G4Electron :: ElectronDefinition（）获得。G4Electron:: Definition（）。

默认提供超过100种粒子，用于各种物理过程。 在正常应用中，用户不需要定义他们自己的粒子。

每个粒子类的唯一对象是在第一次调用其获取指针的静态方法时创建的。 由于粒子是动态对象，应在物理过程初始化之前实例化，因此必须在初始化步骤中显式调用程序所需的所有粒子类的静态方法。 （注意：粒子对象是静态的并且在8.0发布之前自动创建）

\subsubsection{Dictionary of Particles【粒子字典】}
G4ParticleTable类作为粒子字典提供。 提供了各种实用方法，例如：
\begin{lstlisting}[numbers=none]
FindParticle(G4String name);	// find the particle by name
FindParticle(G4int PDGencoding)	// find the particle by PDG encoding .
\end{lstlisting}
G4ParticleTable被定义为一个单独的对象，和静态方法G4ParticleTable :: GetParticleTable（）提供它的指针。
至于重离子（包括超核），对象是由用户和进程的请求动态创建的。 G4ParticleTable类提供了创建离子的方法，例如：
\begin{lstlisting}[numbers=none]
G4ParticleDefinition* GetIon( G4int	atomicNumber,
		G4int	atomicMass,
		G4double	excitationEnergy);
\end{lstlisting}
建模期间粒子会自动注册。 用户无法控制粒子注册。

\subsubsection{Constructing Particles}
ConstructParticle（）是一个纯粹的虚拟方法，其中静态成员函数适用于您需要调用的所有粒子。 这确保了创建这些粒子的对象。
\begin{tcolorbox}
Warning: You must define “ALL PARTICLE TYPES” which are used in your application, except for heavy ions. “ALL PARTICLE TYPES” means not only primary particles, but also all other particles which may appear as secondaries generated by physics processes you use. Beginning with GEANT4 version 8.0, you should keep this rule strictly because all particle definitions are revised to “non-static” objects.
警告：除重离子外，您必须定义应用中使用的“所有颗粒类型”。 “所有粒子类型”不仅意味着原始粒子，而且意味着所有其他粒子可能作为您使用的物理过程产生的次级粒子出现。 从GEANT4版本8.0开始，您应该严格遵守此规则，因为所有粒子定义都修改为“非静态”对象
\end{tcolorbox}
例如，假设您需要一个质子和一个gentino，这是一个用于模拟的虚拟粒子，它不会与材料相互作用。 ConstructParticle（）方法实现如下：
\begin{lstlisting}[caption=Construct a proton and a geantino]
void MyPhysicsList::ConstructParticle()
{
    G4Proton::ProtonDefinition();
    G4Geantino::GeantinoDefinition();
}
\end{lstlisting}
由于GEANT4中有大量的预定义粒子，用这种方法列出所有的粒子是很麻烦的。 如果您需要GEANT4粒子类别中的所有粒子，则有六个实用程序类，对应于每个粒子类别，它们执行此功能:

\begin{itemize}
\item  G4BosonConstructor
\item  G4LeptonConstructor
\item  G4MesonConstructor
\item  G4BaryonConstructor
\item  G4IonConstructor
\item  G4ShortlivedConstructor.
\end{itemize}
下面列出的ExN05PhysicsList中显示了一个例子.
\begin{lstlisting}[caption=Construct all leptons构建所有的轻子]
void ExN05PhysicsList::ConstructLeptons()
{
	// Construct all leptons
	G4LeptonConstructor pConstructor;
	pConstructor.ConstructParticle();
}
\end{lstlisting}
\subsection{Range Cuts范围削减}
为了避免红外发散，一些电磁过程需要一个阈值，低于该阈值不会产生二次发射。 由于这个要求，gammas，电子和正电子需要生产门槛。 这个阈值应该定义为一个距离或范围截止点，它被内部转换为单个材料的能量。 范围阈值应使用G4VUserPhysicsList的SetCuts（）方法在初始化阶段中定义。Cuts per Region将详细讨论阈值和跟踪削减。

\subsubsection{Setting the cuts【设置cuts】}
生产阈值应该在SetCuts（）中定义，它是G4VUserPhysicsList的一个虚拟方法。在调用SetCuts（）之前，应该先构建粒子，材质和过程。 G4RunManager在通常的应用程序中处理这个序列。

该范围切割值是每种材料和每种粒子类型（即电子，正电子和伽玛）的转换阈值能量，使得具有阈值能量的粒子在行进范围切割距离后停止（或被吸收）。另外，从9.3版本开始，这个范围切割值被应用于质子，作为强子弹性过程的原子核的生产阈值。在这种情况下，范围切割值并不意味着行驶距离。阈值能量由切入范围的简单公式计算。

请注意，阈值能量的上限被定义为10GeV。如果要设置较高的阈值能量，可以在设置范围切割之前使用“/ cuts / setMaxCutEnergy”命令更改限制。

“范围内的独特切割值”是GEANT4的重要功能之一，用于以一致的方式处理切割值。对于大多数应用，用户只需要确定一个范围内的一个切割值，并将该值应用于伽玛，电子和正电子等。 （还有质子）

SetCuts（）方法的默认实现提供了一个defaultCutValue成员作为所有粒子类型的唯一范围截止值。 defaultCutValue默认设置为1.0毫米。用户可以通过SetDefaultCutValue（）更改此值可以使用“/ run / setCut”命令以交互方式更改默认剪切值。
\begin{tcolorbox}
Warning: DO NOT change cut values inside the event loop. Cut values may however be changed between runs.
警告：请勿更改事件循环内的切割值。 然而，切割值可能会在运行之间改变。
\end{tcolorbox}
通过使用SetCutValue方法（或者使用“/ run / setCutForGivenParticle”命令），可以为伽马，电子和正电子设置不同的范围切割值。 但是，用户必须注意物理输出，因为GEANT4过程（特别是能量损失）的设计符合“范围内的独特切割值”方案。

从GEANT4版本5.1开始，现在可以为每个几何区域设置生产阈值。 这种新功能在“Cuts per Region”中进行了介绍


\section{How to Specify Physics Processes【如何指定物理过程】}
\subsection{Physics Processes【物理过程】}
物理过程描述粒子如何与材料相互作用。 GEANT4提供了七大类别的流程:
\begin{itemize}
\item  Electromagnetic电磁,
\item  hadronic,强子
\item  transportation运输,
\item  decay,衰变
\item  optical,光
\item  photolepton\_hadron, and
\item  parameterisation.参数设置
\end{itemize}


所有物理过程都来自G4VProcess基类。 它的虚拟方法
\begin{itemize}
\item AtRestDoIt,
\item AlongStepDoIt, and
\item PostStepDoIt
\end{itemize}

and the corresponding methods和相应的方法

\begin{itemize}
\item AtRestGetPhysicalInteractionLength,
\item AlongStepGetPhysicalInteractionLength, and
\item PostStepGetPhysicalInteractionLength
\end{itemize}

描述物理过程在派生类中实现时的行为。 这些方法的细节在Physics Processes中有描述。

以下是用于简单过程的专用基类：

\begin{description}
  \item[G4VAtRestProcess] Processes with only AtRestDoIt
  \item[G4VContinuousProcess] Processes with only AlongStepDoIt
  \item[G4VDiscreteProcess] processes with only PostStepDoIt
\end{description}

还为复杂进程提供了另外4个虚拟类，如G4VContinuousDiscreteProcess.

\subsection{Managing Processes【管理进程】}
G4ProcessManager类包含一个粒子可以进行的进程列表。它包含有关进程调用顺序的信息，以及哪种类型的DoIt方法对列表中的每个进程都有效。 G4ProcessManager对象对应于每个粒子并附加到G4ParticleDefiniton类。

为了验证过程，它们应该在粒子的G4ProcessManager中进行注册。流程ordering信息通过使用AddProcess（）和SetProcessOrdering（）方法包含在内。对于简单进程的注册，可以使用AddAtRestProcess（），AddContinuousProcess（）和AddDiscreteProcess（）方法。

通过使用ActivateProcess（）和InActivateProcess（）方法，G4ProcessManager能够在运行期间打开或关闭一些进程。这些方法仅在进程注册完成后才有效，因此它们不能用于PreInit阶段。

G4VUserPhysicsList类创建G4ProcessManager对象并将其附加到ConstructParticle（）方法中定义的所有粒子类。

\subsection{Specifying Physics Processes【指定物理过程】}

G4VUserPhysicsList是“强制用户类【mandatory user class】”的基类（请参阅如何定义main（）程序），其中必须注册模拟中所需的所有物理过程和所有粒子。 用户必须创建一个从G4VUserPhysicsList派生的类并实现纯虚方法ConstructProcess（）。

例如，如果只需要G4Geantino粒子类，则只需要注册运输过程。 ConstructProcess（）方法然后将被实现如下。

\begin{lstlisting}[caption=Register processes for a geantino.]
void MyPhysicsList::ConstructProcess()
{
// Define transportation process
    AddTransportation();
}
\end{lstlisting}
这里，G4VUserPhysicsList类中提供了AddTransportation（）方法，用于向所有粒子类注册G4Transportation类。 G4Transportation类（和/或相关类）描述了空间和时间中的质点运动。 这是跟踪粒子的强制性过程。

在ConstructProcess（）方法中，物理过程应该创建并注册到每个粒子的G4ProcessManager实例。

G4VUserPhysicsList :: AddTransportation（）方法给出了一个进程注册的例子。

G4ProcessManager中的注册对于其他进程和粒子来说是一个复杂的过程，因为进程之间的关系对于某些进程是至关重要的。 为了简化注册程序，提供了G4PhysicsListHelper。 用户不关心过程类型（即AtRest和/或离散和/或连续）或订购参数。

下面显示了伽马的电磁过程配准示例
\begin{lstlisting}[caption=Register processes for a gamma]
void MyPhysicsList::ConstructProcess()
{
	// Define transportation process
	AddTransportation();
	// electromagnetic processes ConstructEM();
}
void MyPhysicsList::ConstructEM()
{
	// Get pointer to G4PhysicsListHelper
	G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
	// Get pointer to gamma
	G4ParticleDefinition* particle = G4Gamma::GammaDefinition();
	// Construct and register processes for gamma
	ph->RegisterProcess(new G4PhotoElectricEffect(), particle);
	ph->RegisterProcess(new G4ComptonScattering(), particle);
	ph->RegisterProcess(new G4GammaConversion(), particle);
	ph->RegisterProcess(new G4RayleighScattering(), particle);
}
\end{lstlisting}
\section{How to Generate a Primary Event【如何生成主事件】
}
\subsection{Generating Primary Events【生成主要事件】}
G4VuserPrimaryGeneratorAction是派生自己的具体类的强制类之一。 在具体的课程中，您必须指定应该如何生成主要事件。 实际的一次粒子生成将由具体的G4VPrimaryGenerator类完成，在下面的小节中进行解释。 您的G4VUserPrimaryGeneratorAction具体类只是安排生成初级粒子的方式{translate by九九之九}。

\begin{lstlisting}[caption=ExG4PrimaryGeneratorAction01：使用G4ParticleGun的G4VUserPrimaryGeneratorAction具体类的示例。 有关G4Particle Gun的使用，请参阅下一小节]
//////////////////////////////////
// ExG4PrimaryGeneratorAction01.hh
//////////////////////////////////
#ifndef ExG4PrimaryGeneratorAction01_h
#define ExG4PrimaryGeneratorAction01_h 1
#include "G4VUserPrimaryGeneratorAction.hh"
#include "G4ThreeVector.hh"
#include "globals.hh"
class G4ParticleGun;
class G4Event;
class ExG4PrimaryGeneratorAction01 : public G4VUserPrimaryGeneratorAction
{ public:
	ExG4PrimaryGeneratorAction01(
			const G4String& particleName = "geantino",
			G4double energy = 1.*MeV,
			G4ThreeVector position= G4ThreeVector(0,0,0),
			G4ThreeVector momentumDirection = G4ThreeVector(0,0,1));
	~ExG4PrimaryGeneratorAction01();

	// methods
	virtual void GeneratePrimaries(G4Event*);
	private:
	// data members
	G4ParticleGun* fParticleGun; //pointer a to G4 service class
};
#endif
//////////////////////////////////
// ExG4PrimaryGeneratorAction01.cc
//////////////////////////////////
#include "ExG4PrimaryGeneratorAction01.hh"
#include "G4Event.hh"
#include "G4ParticleGun.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ExG4PrimaryGeneratorAction01::ExG4PrimaryGeneratorAction01(
		const G4String& particleName,
		G4double energy,
		G4ThreeVector position,
		G4ThreeVector momentumDirection) : G4VUserPrimaryGeneratorAction(),
	fParticleGun(0)
{
	G4int nofParticles = 1;
	fParticleGun = new G4ParticleGun(nofParticles);
	// default particle kinematic
	G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
	G4ParticleDefinition* particle
		= particleTable->FindParticle(particleName);
	fParticleGun->SetParticleDefinition(particle);
	fParticleGun->SetParticleEnergy(energy);
	fParticleGun->SetParticlePosition(position);
	fParticleGun->SetParticleMomentumDirection(momentumDirection);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
ExG4PrimaryGeneratorAction01::~ExG4PrimaryGeneratorAction01()
{
	delete fParticleGun;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void ExG4PrimaryGeneratorAction01::GeneratePrimaries(G4Event* anEvent)
{
	// this function is called at the beginning of event
	fParticleGun->GeneratePrimaryVertex(anEvent);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......

\end{lstlisting}
\subsubsection{Selection of the generator【generator的选择】
}
在你的G4VUserPrimaryGeneratorAction的构造函数中，你应该实例化主生成器。 如有必要，您需要为发生器设置一些初始条件。

在ExG4PrimaryGeneratorAction01中，G4ParticleGun被构造为用作实际的一次粒子生成器。 G4ParticleGun的方法在下一节中介绍。 请注意，您的G4VUserPrimaryGeneratorAction具体类中构造的主生成器对象必须在析构函数中被删除。
\subsubsection{Generation of an event【生成一个事件】}
G4VUserPrimaryGeneratorAction有一个名为generatePrimaries（）的纯虚拟方法。 这个方法在每个事件的开始时被调用。 在此方法中，您必须调用通过generatePrimaryVertex（）方法实例化的G4VPrimaryGenerator具体类。

您可以调用多个generator和/或多次调用一个generator。 混合几个generator可能会产生更复杂的primary event。

\subsection{G4VPrimaryGenerator【G4主发生器】}
GEANT4提供了三个G4VPrimaryGenerator具体类。 这些G4ParticleGun和G4GeneralParticleSource将在这里讨论。 第三个是G4HEPEvtInterface，它将在Event Generator Interface中进行讨论。

\subsubsection{G4ParticleGun【G4粒子枪】}
G4ParticleGun是由GEANT4提供的generator。 这个类产生具有给定动量和位置的初级粒子。 它不提供任何形式的随机化。

G4ParticleGun的构造函数采用一个整数，该整数会导致生成一个或多个具有完全相同运动特性的原色。 产生具有随机能量，动量和/或位置是用户的相当频繁需求。 这种随机化可以通过调用G4ParticleGun提供的各种设置方法来实现。【译者注：可定义X,Y,Z为随机random变量】 在调用G4ParticleGun的generatePrimaryVertex（）之前，应该在具体的G4VUserPrimaryGeneratorAction类的generatePrimaries（）方法中实现这些方法的调用。 GEANT4提供各种分布的随机数生成方法（请参阅全局使用类）。

\subsubsection{Public methods of G4ParticleGun【G4粒子枪的公开方法】}
G4ParticleGun提供了以下方法，并且可以从具体的G4VUserPrimaryGeneratorAction类中的generatePrimaries（）方法调用它们.
\begin{itemize}
\item void SetParticleDefinition(G4ParticleDefinition*)
\item void SetParticleMomentum(G4ParticleMomentum)
\item void SetParticleMomentumDirection(G4ThreeVector)
\item void SetParticleEnergy(G4double)
\item void SetParticleTime(G4double)
\item void SetParticlePosition(G4ThreeVector)
\item void SetParticlePolarization(G4ThreeVector)
\item void SetNumberOfParticles(G4int)

\end{itemize}

对于许多应用G4ParticleGun是一个合适的粒子发生器。 但是，如果您想以更复杂的方式生成原生粒子，则可以使用G4GeneralParticleSource，GEANT4通用粒子源模块（GPS），在下一节（General Particle Source）中讨论。
\section{GEANT4 General Particle Source【GEANT4通用粒子源】}
\subsection{Introduction【介绍】}
G4GeneralParticleSource（GPS）是用于Monte-Carlo高能粒子传输的GEANT4工具包的一部分。 具体来说，它允许规定主源粒子的光谱，空间和角度分布。 这里介绍GPS类结构的概述。 配置涵盖用户应用程序的GPS配置，宏命令描述宏命令界面。 示例宏文件给出了一个示例输入文件来指导第一次用户。

G4GeneralParticleSource的使用方式与GEANT4应用程序中的G4ParticleGun完全相同。 在现有应用程序中，可以通过全局变量G4ParticleGun和G4GeneralParticleSource来简单地更改PrimaryGeneratorAction。 GPS可以通过命令行或基于宏的输入进行配置。 有经验的用户也可以使用技术说明中详细描述的GPS的方法和类来对分布进行硬编码{translate by九九之九}。

GPS的类图如图2.1所示。 从版本10.01开始，引入了拆分类机制以减少多线程模式下的内存使用量。 G4GeneralParticleSourceData类是一个线程安全的单例，它提供对G4GeneralParticleSource类的源信息的访问。 G4GeneralParticleSourceData类可以有多个G4SingleParticleSource类的实例，每个实例具有独立的位置，角度和能量分布以及入射粒子类型。 对用户来说，这种改变应该是透明【transparent】的。

 \begin{figure}[htbp]               % 控制插图位置
   \setlength{\abovecaptionskip}{0pt}
   \setlength{\belowcaptionskip}{10pt}
                                     % 控制图形和上下文的距离
   \centering                       % 使图形居中显示
   \includegraphics[width=0.8\textwidth]{GPS.png}
                                     % 控制图形显示宽度为0.8\textwidth
   \caption{The class diagram of G4GeneralParticleSource} \label{fig:G4GeneralParticleSource}
                                     % 图形题目和交叉引用标签
   {\footnotesize 通用粒子源是产生初级粒子的一种有效方法}
 \end{figure}

\subsection{Configuration【配置】}
GPS允许用户控制主要颗粒的以下特征
\begin{itemize}
\item Spatial sampling:空间采样：在简单的2D或3D表面上，如光盘，球体和盒子
\item Angular distribution:角度分布：单向，各向同性，余弦定律，波束或任意（用户定义）.
\item Spectrum:频谱：线性，指数，幂律，高斯，黑体或分段拟合数据.
\item Multiple sources:多种来源：可以在同一运行中使用多个独立来源.
\end{itemize}

如上所述，G4GeneralParticleSource的使用方式与GEANT4应用程序中的G4ParticleGun完全相同，可以通过现有应用程序源代码中的“全局搜索和替换【global search and replace】”替代后者。

\subsubsection{Position Distribution【位置分布】}
位置分布可以通过使用几个基本形状来定义，以包含粒子的起始位置。最简单的源代码定义是一个点源。人们也可以定义平面源，其中粒子从圆形，环形，椭圆形，正方形或长方形发出。还有定义1D或2D加速器束点的方法。这五个平面是在x-y平面中定向的。要定义一个圆圈，就要给出半径，对于圆环来说，需要给出内半径和外半径，而对于一个椭圆来说，一个正方形或者一个矩形给出了x和y中的半长度。
更复杂的是，人们可以定义表面或体积源，其中输入粒子可以被限制在三维形状的表面或其整个体积内。 G4GeneralParticleSource中使用的四个3D形状是球体，椭球体，圆柱体和平行六面体【sphere, ellipsoid, cylinder and parallelepiped】。球体可以通过指定半径来简单定义。椭圆体是通过在x，y和z中给出它们的半长来定义的。气缸被定义为使得轴线平行于z轴线，因此用户需要给出半径和z半长度。平行六面体通过给定x，y和z半长度以及角度α，θ和φ来定义（图2.2）。


 \begin{figure}[htbp]               % 控制插图位置
   \setlength{\abovecaptionskip}{0pt}
   \setlength{\belowcaptionskip}{10pt}
                                     % 控制图形和上下文的距离
   \centering                       % 使图形居中显示
   \includegraphics[width=0.8\textwidth]{GPSparallelpiped.png}
                                     % 控制图形显示宽度为0.8\textwidth
   \caption{The angles used in the definition of a Parallelepiped用于定义平行六面体的角度.} \label{fig:GPSparallelpiped}
                                     % 图形题目和交叉引用标签
   {\footnotesize }
 \end{figure}

 为了容易定义源，如上所述，假定平面和形状沿着与坐标轴的特定方向定向。 对于更一般的应用，用户可以提供两个矢量（x'和平面x'-y'中的矢量），以便相对于整个坐标系统旋转形状的坐标轴（图2.3）。 旋转矩阵在G4GeneralParticleSource中自动计算。 粒子的起点始终均匀地分布在2D或3D表面上，尽管偏置【biasing】可以改变这一点。

\subsubsection{ Angular Distribution【角度分布】}
角分布用于控制粒子从源点发出/入射的方向。 通常有三个主要选择，各向同性，余弦定律或用户定义。 另外还有选择
 \begin{figure}[htbp]               % 控制插图位置
   \setlength{\abovecaptionskip}{0pt}
   \setlength{\belowcaptionskip}{10pt}
                                     % 控制图形和上下文的距离
   \centering                       % 使图形居中显示
   \includegraphics[width=0.8\textwidth]{GPSrotation.png}
                                     % 控制图形显示宽度为0.8\textwidth
   \caption{An illustration of the use of rotation matrices.一个使用旋转矩阵的例子。 } \label{fig:GPSrotation}
                                     % 图形题目和交叉引用标签
   {\footnotesize  A cylinder is defined with its axis parallel to the z-axis (black lines), but the definition of 2 vectors can rotate it into the frame given by x’, y’, z’ (red lines). 圆柱的轴线与z轴平行（黑线），但2个矢量的定义可以将它旋转到由x'，y'，z'（红线）给出的框架中。}
 \end{figure}

 指定平行光束以及不同的加速器光束。各向同性分布表示从均匀4π通量中可以看到什么。余弦定律表示从均匀的2π通量在一个平面上看到的分布。

 对于任何预定义分布，可以偏置（偏置）【bias (Biasing)】θ和φ，包括将下限和上限设置为θ和φ。用户定义的分布不能有额外的偏差（任何偏差显然应该纳入到用户定义中）。

 顶角【zenith】θ= 0的事件意味着粒子沿着-z轴行进。在为角分布指定用户定义的坐标时，牢记这一点很重要。如果用户旋转了位置分布，用户必须小心旋转角度分布的坐标轴（图2.3）。

 用户定义的分布要求用户输入θ或φ或两者的直方图。用户定义的分布可以相对于坐标轴或相对于形状或体积的表面法线来指定。相对于表面法线的分布，θ应该只在0和π/ 2之间定义，而不是通常的0到π范围。

 顶层/ gps / direction命令使用方向余弦来指定初级粒子方向，如下所示:

\begin{equation}\label{立体角公式}
\begin{array}{l}
{P_x} =  - {\rm{s}}in\theta cos\varphi \\
{P_y} =  - sin\theta sin\varphi \\
{P_z} =  - cos\theta
\end{array}
\end{equation}
\subsubsection{Energy Distribution【能量分布】}
输入粒子的能量可以设置为遵循几个内置函数或用户定义的函数，如表2.1所示。 用户可以偏置任何预定义的能量分布以加速模拟（用户定义的分布已经偏向，通过构建）

\begin{table}[htbp]
\centering
\caption{Energy distribution commands能量分布命令}
\tiny
\begin{tabular}{l|p{0.1\textwidth}|l|p{3cm}l|p{3cm}}
  \toprule
  % after \\: \hline or \cline{col1-col2} \cline{col3-col4} ...
Spectrum	&	Abbreviation	&	Functional Form	&	User Parameters	\\
光谱	&	缩写	&	功能表	&用户参数		\\ \midrule
mono-energetic单能	&	Mono	&	$I \propto \delta \left( {E - {E_0}} \right)$	&	Energy $E_0$	\\\hline
linear线性	&	Lin	&	$I \propto {I_0} + m \times E$	&	Intercept $I_0$, slope m	\\\hline
Exponential指数	&	Exp	&	$I \propto {\rm{ }}exp\left( { - E/{E_0}} \right)$	&	Energy scale-height $E_0$	\\\hline
power-law幂律	&	Pow	&	$I \propto {E^\alpha }$	&	Spectral index $\alpha $	\\\hline
Gaussian高斯	&	Gauss	&$I{\rm{ = (}}2\pi \sigma {)^{ - {1 \over 2}}}\exp [ - {(E/{E_0})^2}/{\sigma ^2}]$&	Mean energy $E_0$, standard deviation $\sigma$	\\\hline
bremsstrahlung轫致辐射	&	Brem	&	$I{\rm{ = }}{\int {2{E^2}[{h^2}{c^2}(exp( - E/kT) - 1)]} ^{ - 1}}$	&	Temperature T	\\\hline
black body黑色的身体	&	Bbody	&	$I \propto (kT)^\frac{1}{2} E \exp(-E/kT)$	&	Temperature (see text)	\\\hline
cosmic diffuse gamma ray宇宙漫射伽玛射线	&	Cdg	&	$I \propto {[{(E/{E_0})_{\alpha 1}} + {(E/{E_0})_{\alpha 2}}]^{ - 1}}$	&	Energy range $E_{min}$ to $E_{max}$; energy $E_b$ and indices ${\alpha 1}$ and ${\alpha 1}$ are fixed (see text)	\\\bottomrule
\end{tabular}
\end{table}


用户还可以选择以能量（“用户User”）或每个核子的能量（“Epn”）定义直方图，或者给出可以适合各种简单函数的任意点分光谱（“Arb”） 。直方图或点谱的数据必须以升序（横坐标）顺序提供。逐点频谱可以是微分的（如分箱直方图）或积分（累积分布函数）。如果积分，输入时$e1 < e2$的数据必须满${\rm{s(e1)}} \ge {\rm{s(e2)}}$;这不是由GPS代码验证的。整个频谱的最大能量由最后一个数据点定义，因为GPS在内部转换为差分频谱。

与其他光谱分布不同，证明难以无限期地整合黑体光谱，并且这导致了另一种方法。相反，它已经决定使用黑体公式创建一个10,000 bin直方图，然后从中产生随机能量。

同样，宇宙漫射伽马射线的破碎幂律使得产生不确定的积分CDF成为问题。相反，由用户指定的最小和最大能量用于构造从中选择随机能量的定积分CDF。

\subsubsection{Biasing【偏倚】}
用户可以通过输入直方图来偏差分布。这是从中挑选数量有偏差的随机数，因此只需要从0到1的直方图。使用此选项时必须非常小心，因为计算数量的方式会影响偏差的工作方式，如下所述。偏差直方图以与其他用户定义的直方图相同的方式输入。

在创建偏置直方图时，记住从这些数字生成数量的方式非常重要。例如，让我们比较$\theta $分布的偏差与$\phi $分布的偏差。让我们将$\theta $和$\phi $范围分成10个分箱，然后决定我们要将生成的值限制在第一个和最后一个分箱。这给出了0到0.628和5.655到6.283的新的$\phi $范围。由于$\phi $是使用$\phi  = 2\pi RNDM$计算的，所以这种简单的偏置将正确工作。

如果我们现在看$\theta $，我们希望选择0到0.314（对于${\rm{0}} \le {\rm{RNDM}} \le {\rm{0}}{\rm{.1}}$）和2.827到3.142（对于${\rm{0}} \le {\rm{RNDM}} \le {\rm{0}}{\rm{.9}}$）这两个范围中的值。但是，根据公式$\theta  = \arccos (1 - 2 \times RNDM)$计算极角$\theta $。由此我们看到0.1给出0.644的$\theta $，而0.9的RNDM给出2.498的$\theta $。这意味着上述内容不会像用户所希望的那样偏离分配。因此，用户在尝试应用偏置方案时必须考虑用于生成随机数量的方法。一些数量，如x，y，z和$\phi $会相对容易偏差，但其他数量可能需要更多思考

\subsubsection{User-Defined Histograms【用户定义的直方图】}
用户可以根据几个原因定义直方图：θ或φ中的角分布; 能量分配; 每个核子分布的能量; 或偏置x，y，z，$\theta $，或能量。 尽管原因可能与此不同。

要选择直方图，使用命令/gps/hist/type（宏命令Macro Commands）。如果想要输入角度分布，可以输入“theta”或“phi”作为参数。通过使用/gps/hist/point命令，一次加载一个bin，然后是两个参数，即bin的上边界和bin的权重（或区域）。因此直方图是差分函数。

目前直方图仅限于1024个分档。每个用户输入数据对的第一个值被视为直方图箱的上边缘，第二个值是箱内容。例外是用户输入的第一个数据对，其第一个值被视为直方图第一个仓的下边缘，第二个值未被使用。此规则适用于所有分布直方图以及偏移的直方图。

用户必须意识到直方图的局限性。例如，通常θ被定义在0和$\pi$之间，并且φ被定义在0和2$\pi$之间，所以定义在这些限制之外的直方图可能不会给用户他们想要的东西（另请参阅偏置Biasing）。
\subsection{Macro Commands【宏命令】}

G4GeneralParticleSource可以通过从/gps命令目录树中键入命令来配置，或者在g4macro文件中包含/gps命令来配置。

\subsubsection{G4ParticleGun equivalent commands【G4粒子枪的命令】}

\begin{table}[H]
\centering
\caption{G4ParticleGun equivalent commands.}
\scriptsize
\begin{tabular}{l|p{0.1\textwidth} |p{0.6\textwidth}}
\toprule
Command	&	Arguments	&	Description and restrictions	\\
\midrule
/gps/List	&		&	List available incident particles列出可用的事件粒子	\\\hline
/gps/particle	&	name	&	Defines the particle type [default geantino], using GEANT4 naming convention. 使用GEANT4命名约定定义粒子类型[默认geantin]。	\\\hline
/gps/direction	&	Px Py Pz	&	Set the momentum direction [default (1,0,0)] of generated particles using (2.1) 设置生成粒子的动量方向	\\\hline
/gps/energy	&	E unit	&	Sets the energy [default 1 MeV] for mono-energetic sources. The units can be eV, keV, MeV, GeV, TeV or PeV. (NB: it is recommended to use /gps/ene/mono instead.) 为单能源设置能量[默认1 MeV]	\\\hline
/gps/position	&	X Y Z unit	&	Sets the centre co-ordinates (X,Y,Z) of the source [default (0,0,0) cm]. The units can be micron, mm, cm, m or km. (NB: it is recommended to use /gps/pos/centre instead.) 设置源的中心坐标[默认（0,0,0）cm]	\\\hline
/gps/ion	&	Z A Q E	&	After /gps/particle ion, sets the properties (atomic number Z, atomic mass A, ionic charge Q, excitation energy E in keV) of the ion.	\\\hline
	&		&	在/ gps /粒子离子之后，设定离子的性质（原子序数Z，原子质量A，离子电荷Q，keV中的激发能E）。	\\\hline
/gps/ionLvl	&	Z A Q lvl	&	After /gps/particle ion, sets the properties (atomic number Z, atomic mass A, ionic charge Q, Number of metastable state excitation level (0-9) of the ion.    / gps /粒子离子后，设定离子的性质（原子序数Z，原子质量A，离子电荷Q，亚稳状态激发能级数（0-9））。	\\\hline
/gps/time	&	t0 unit	&	Sets the primary particle (event) time [default 0 ns]. The units can be ps, ns, us, ms, or s. 设置主要粒子（事件）时间[默认0纳秒]	\\\hline
/gps/polarization	&	Px Py Pz	&	Sets the polarization vector of the source, which does not need to be a unit vector. 设置源的偏振矢量，该矢量不需要是单位矢量。	\\\hline
/gps/number	&	N	&	Sets the number of particles [default 1] to simulate on each event.	\\\hline
/gps/verbose	&	level	&	Control the amount of information printed out by the GPS code. Larger values produce more detailed output. 控制GPS代码打印的信息量。较大的值会产生更详细的输出.\\\hline
/gps/polarization	&	Px Py Pz	&	Sets the polarization vector of the source, which does not need to be a unit vector. 设置源的偏振矢量，该矢量不需要是单位矢量。\\\hline
/gps/number	&	N	&	Sets the number of particles [default 1] to simulate on each event.\\\hline
/gps/verbose	&	level	&	Control the amount of information printed out by the GPS code. Larger values produce more detailed output. 控制GPS代码打印的信息量。较大的值会产生更详细的输出。\\

\bottomrule
\end{tabular}
\end{table}

\subsubsection{Multiple source specification【多源指定】}
\begin{table}[H]
\centering
\caption{Multiple source specification多源指定}
\scriptsize
\begin{tabular}{l|p{0.1\textwidth} |p{0.6\textwidth}}
\toprule
Command	&	Arguments	&	Description and restrictions	\\\midrule
/gps/source/add	&	intensity	&	添加具有指定强度的新粒子源	\\\hline
/gps/source/list	&		&	List the particle sources defined. 列出定义的粒子源。	\\\hline
/gps/source/clear	&		&	Remove all defined particle sources. 删除所有定义的粒子源。	\\\hline
/gps/source/show	&		&	Display the current particle source显示当前的粒子源	\\\hline
/gps/source/set	&	index	&	选择指定的粒子源作为当前的粒子源。	\\\hline
/gps/source/delete	&	index	&	删除指定的粒子源。	\\\hline
/gps/source/ multiplevertex	&	flag	&	Specify true for simultaneous generation of multiple vertices, one from each specified source. False [default] generates a single vertex, choosing one source randomly.	\\\hline
	&		&	指定true用于同时生成多个顶点，每个指定的源都有一个顶点。 False [默认]生成一个顶点，随机选择一个源。	\\\hline
/gps/source/ intensity	&	intensity	&	Reset the current source to the specified intensity	\\\hline
	&		&	将电流源重置为指定的强度	\\\hline
/gps/source/ flatsampling	&	flag	&	Set to True to allow biased sampling among the sources. Setting to True will ignore source intensities. The default is False. 设置为True以允许源中的偏置采样。 设置为True将忽略源强度。 默认值是False。	\\
\bottomrule
\end{tabular}
\end{table}

\subsubsection{Source position and structure【源位置和结构】}
\begin{table}[H]
\centering
\caption{Source position and structure源位置和结构}
\scriptsize
\begin{tabular}{l|p{0.1\textwidth} |p{0.6\textwidth}}
\toprule
Command	&	Arguments	&	Description and restrictions	\\\midrule
/gps/pos/type	&	dist	&	设置源位置分布类型：点[默认]，平面，光束，曲面，体积。Point [default], Plane, Beam, Surface, Volum{translate by九九之九}	\\\hline
/gps/pos/shape	&	shape	&	在使用/ gps / pos / type之后设置源形状类型。 对于平面，这可以是圆形，环形，椭圆形，方形，矩形。 对于表面或体积来源，这可以是球体，椭球体，圆柱体，（平行六面体）。Sphere, Ellipsoid, Cylinder, Para (parallelepiped).		\\\hline
/gps/pos/centre	&	X Y Z unit	&	设置源[默认（0,0,0）cm]的中心坐标（X，Y，Z）。单位只能是微米，毫米，厘米，米或公里。 	\\\hline
/gps/pos/rot1	&	R1x R1y R1z	&	定义第一个（x'方向）矢量R1 [default（1,0,0）]，它不需要是单位矢量，并与/ gps / pos / rot2一起使用来创建形状的旋转矩阵 用/ gps / shape定义。	\\\hline
/gps/pos/rot2	&	R2x R2y R2z	&	定义xy平面[default（0,1,0）]中的第二个向量R2，它不需要是单位向量，并与/ gps / pos / rot1一起使用以创建定义的形状的旋转矩阵 与/ gps /形状。	\\\hline
/gps/pos/halfx	&	len unit	&	设置源的x [默认0 cm]的半长度。 	\\\hline
/gps/pos/halfy	&	len unit	&	设置源的y [默认0 cm]的半长度。	\\\hline
/gps/pos/halfz	&	len unit	&	设置源的z [默认0 cm]的半长度。 	\\\hline
/gps/pos/radius	&	len unit	&	设置源的半径[默认为0厘米]或环形的外半径。	\\\hline
/gps/pos/inner\_radius	&	len unit	&	设置环形的内半径[默认为0厘米]。	\\\hline
/gps/pos/sigma\_r	&	sigma unit	&	设置光束位置轮廓的横向（径向）标准偏差[默认0厘米]。	\\\hline
/gps/pos/sigma\_x	&	sigma unit	&	在x方向上设置光束位置轮廓的标准偏差[默认0厘米]。 	\\\hline
/gps/pos/sigma\_y	&	sigma unit	&	在y方向上设置光束位置轮廓的标准偏差[默认0 cm]。 	\\\hline
/gps/pos/paralp	&	alpha unit	&	与平行六面体一起使用。 在y和+ y处，由y轴和连接平行于zx平面的面中心的平面形成的角度[默认0弧度]α。 单位只能是deg或rad。	\\\hline
/gps/pos/parthe	&	theta unit	&	与平行六面体一起使用。 极点角度[默认0弧度]将连线在z处的面部中心与在+ z处脸部中心相连的线的θ。 单位只能是deg或rad。	\\\hline
/gps/pos/parphi	&	phi unit	&	与平行六面体一起使用。 将z面上的脸部中心与+ z面上的面部中心相连的线的方位角[默认0弧度]φ。 单位只能是deg或rad。	\\\hline
/gps/pos/confine	&	name	&	允许用户将源限制为物理体名称[默认为NULL]。	\\
\bottomrule
\end{tabular}
\end{table}

\subsubsection{Source direction and angular distribution【源方向和角度分布】}
\begin{table}[H]
\centering
\caption{Source direction and angular distribution. 源方向和角度分布}
\scriptsize
\begin{tabular}{l|p{0.1\textwidth} |p{0.6\textwidth}}
\toprule
Command	&	Arguments	&	Description and restrictions	\\\hline
/gps/ang/type	&	AngDis	&	将角度分布类型（iso [default]，cos，planar，beam1d，beam2d，focused，user）设置为各向同性，余弦定律或用户定义。.	\\\hline
/gps/ang/rot1	&	AR1x AR1y AR1z	&	定义角度分布的第一个（x'方向）旋转矢量AR1 [默认（1,0,0）]，不一定是单位矢量。 与/ gps / ang / rot2一起使用来计算角度分布旋转矩阵。	\\\hline
/gps/ang/rot2	&	AR2x AR2y AR2z	&	在xy平面中定义第二个旋转矢量AR2 [角度分布的默认（0,1,0）]，该角度分布不一定必须是单位矢量。 与/ gps / ang / rot2一起使用来计算角度分布旋转矩阵。	\\\hline
/gps/ang/mintheta	&	MinTheta unit	&	为θ分布设置最小值[默认0弧度]。 单位可以是deg或rad。	\\\hline
/gps/ang/maxtheta	&	MaxTheta unit	&	为θ分布设置最大值[默认π弧度]。 单位可以是deg或rad。	\\\hline
/gps/ang/minphi	&	MinPhi unit	&	为φ分布设置最小值[默认0弧度]。 单位可以是deg或rad。	\\\hline
/gps/ang/maxphi	&	MaxPhi unit	&	为φ分布设置最大值[默认2π弧度]。 单位可以是deg或rad。	\\\hline
/gps/ang/sigma\_r	&	sigma unit	&	设置径向光束方向轮廓的标准偏差[默认0弧度]。 单位只能是deg或rad。	\\\hline
/gps/ang/sigma\_x	&	sigma unit	&	在x方向上设置光束方向轮廓的标准偏差[默认0弧度]。 单位只能是deg或rad。	\\\hline
/gps/ang/sigma\_y	&	sigma unit	&	在y方向上设置光束方向轮廓的标准偏差[默认0弧度]。 单位只能是deg或rad。	\\\hline
/gps/ang/focuspoint	&	X Y Z unit	&	设置光束[默认（0,0,0）厘米]的对焦点（X，Y，Z）。 单位只能是微米，毫米，厘米，米或公里。	\\\hline
/gps/ang/user\_coor	&	bool	&	计算相对于用户定义的坐标系（true）或全局坐标系（false，default）的角度分布。	\\\hline
/gps/ang/surfnorm	&	bool	&	允许用户选择角度分布是否相对于用户定义分布的坐标系（false, default）或曲面法线（true）。	\\\\
\bottomrule
\end{tabular}
\end{table}
\subsubsection{Energy spectra【能谱】}
\begin{table}[H]
\centering
\caption{Source energy spectra. 能谱}
\scriptsize
\begin{tabular}{l|p{0.1\textwidth} |p{0.6\textwidth}}
\toprule
Command	&	Arguments	&	Description and restrictions	\\\midrule
/gps/ene/type	&	EnergyDis	&	将能量分布类型设置为下列之一（见表2.1）：单声道【Momo】（单能，默认），Lin（线性），Pow（幂律），Exp（指数），Gauss（高斯），Brem（韧致辐射） ，Bbody（黑体），Cdg（宇宙漫射伽马射线），用户（用户自定义直方图），Arb（逐点谱），Epn（能量 - 每核子直方图）	\\\hline
/gps/ene/min	&	Emin unit	&	设置能量分配的最小[默认0 keV]。 这些单位可以是eV，keV，MeV，GeV，TeV或PeV。	\\\hline
/gps/ene/max	&	Emax unit	&	为能量分配设置最大[默认0 keV]。 这些单位可以是eV，keV，MeV，GeV，TeV或PeV。	\\\hline
/gps/ene/mono	&	E unit	&	为单能源设置能量[默认1 MeV]。 这些单位可以是eV，keV，MeV，GeV，TeV或PeV。	\\\hline
/gps/ene/sigma	&	sigma unit	&	为高斯或单能量分布设置能量的标准偏差[默认0keV]。 这些单位可以是eV，keV，MeV，GeV，TeV或PeV。	\\\hline
/gps/ene/alpha	&	alpha	&	为幂律分布设置指数α[默认0]。	\\\hline
/gps/ene/temp	&	T	&	将黑体和韧辐射光谱的温度设置为kelvins [默认为0]。	\\\hline
/gps/ene/ezero	&	E0	&	针对指数分布设置比例E0 [默认值0]。	\\\hline
/gps/ene/gradient	&	gradient	&	为线性分布设置梯度（斜率）[默认为0]。	\\\hline
/gps/ene/intercept	&	intercept	&	设置线性分布的Y截距[默认0]。	\\\hline
/gps/ene/biasAlpha	&	alpha	&	为有偏幂律分布设置指数α[默认值0]。 偏倚权重由幂律概率分布确定。	\\\hline
/gps/ene/calculate	&		&	为内部分档的宇宙漫射伽马射线（Cdg）和黑体（Bbody）分布准备完整的PDF。	\\\hline
/gps/ene/emspec	&	bool	&	允许用户指定分布处于动量（false）或能量（true，默认）。 仅对用户和Arb分配有效。	\\\hline
/gps/ene/diffspec	&	bool	&	允许用户指定点式频谱是整数（false）还是差分（true，默认）。 积分频谱仅适用于Arb分布。	\\
\bottomrule
\end{tabular}
\end{table}

\subsubsection{User-defined histograms and interpolated functions【用户定义的直方图和插值函数】}
\begin{table}[H]
\centering
\caption{User-defined histograms and interpolated functions【用户定义的直方图和插值函数】}
\scriptsize
\begin{tabular}{l|p{0.1\textwidth} |p{0.6\textwidth}}
\toprule
Command	&	Arguments	&	Description and restrictions	\\\midrule
/gps/hist/type	&	type	&	设置直方图类型：预定义偏移量[默认值]，biasy，biasz，biast（角度θ，biasp（角度φ），biaspt（位置θ，biaspp（位置φ），偏置;用户定义的直方图theta，phi，energy，arb （逐点），epn（每个核子的能量）。	\\\hline
/gps/hist/reset	&	type	&	重新设置指定的直方图： biasx [default], , biasy, biasz, biast, biasp, biaspt, biaspp, biase, theta, phi, energy, arb, epn.	\\\hline
/gps/hist/point	&	Ehi Weight	&	在直方图（其中Ehi是箱上边缘）或点分布（其中Ehi是横坐标）中指定一个条目（包含内容重量）。横坐标Ehi必须采用GEANT4默认单位（MeV代表能量，rad代表角度）。	\\\hline
/gps/hist/file	&	HistFile	&	在ASCII文件中导入任意能量直方图。格式应该是文件每行一个Ehi权重对，遵循用户定义的直方图和内插函数中的详细说明对于直方图，Ehi是容器上边缘，对于逐点分布，Ehi是横坐标。横坐标Ehi必须采用GEANT4默认单位（MeV代表能量，rad代表角度）。	\\\hline
/gps/hist/inter	&	type	&	设置点光谱的插值类型（Lin线性，Log对数，Exp指数，样条三次样条）。该命令必须在最后一个数据点之后立即发出。	\\	\\
\bottomrule
\end{tabular}
\end{table}


\subsection{Example Macro File【示例宏文件】}
\begin{lstlisting}[numbers=none,language=bash]
# Macro test2.g4mac
/control/verbose 0
/tracking/verbose 0
/event/verbose 0
/gps/verbose 2
/gps/particle gamma
/gps/pos/type Plane
/gps/pos/shape Square
/gps/pos/centre 1 2 1 cm
/gps/pos/halfx 2 cm
/gps/pos/halfy 2 cm
/gps/ang/type cos
/gps/ene/type Lin
/gps/ene/min 2 MeV
/gps/ene/max 10 MeV
/gps/ene/gradient 1
/gps/ene/intercept 1
/run/beamOn 10000
\end{lstlisting}

上面的宏定义了一个平面源，形状为正方形，长4厘米，宽4厘米，中心位于（1,2,1）厘米处。 默认情况下，该平面的法线是z轴。 角分布遵循余弦定律。 能谱是线性的，梯度和截距等于1，并且从2到10MeV延伸，将产生10,000个初始事件【primaries】。

如图2.4所示，标准的GEANT4输出应显示初级粒子从1,0,1和3,4,1（cm）开始，能量在2到10 MeV之间，其中我们绘制了实际 能量，位置和由上述宏文件生成的主要粒子的角度分布。

 \begin{figure}[htbp]               % 控制插图位置
   \setlength{\abovecaptionskip}{0pt}
   \setlength{\belowcaptionskip}{10pt}
                                     % 控制图形和上下文的距离
   \centering                       % 使图形居中显示
   \includegraphics[width=0.8\textwidth]{GPSexample.png}
                                     % 控制图形显示宽度为0.8\textwidth
   \caption{由上面显示的宏文件生成的初级粒子的能量，位置和角度分布 } \label{fig:GPSexample}
                                     % 图形题目和交叉引用标签
   {\footnotesize }
 \end{figure}
.
\section{How to Make an Executable Program【如何制作可执行程序 .exe】}

Geant4中用户示例的代码放置在主GEANT4源包的子目录示例中。 该目录安装到安装前缀下的share / Geant4-G4VERSION / examples（其中G4VERSION是GEANT4版本号）子目录中。 在下面的章节中，我们将简要介绍如何使用CMake和现在已过时的Geant4Make系统构建一个具体示例“ExampleB1”，它是GEANT4发行版的一部分{translate by九九之九}。

\subsection{Using CMake to Build Applications[使用CMake构建应用程序]}

GEANT4安装一个名为Geant4Config.cmake的文件位于
\begin{lstlisting}[numbers=none,language=bash]
+- CMAKE_INSTALL_PREFIX
   +- lib/
      +- Geant4-G4VERSION/
         +- Geant4Config.cmake
\end{lstlisting}
它是专为与CMake find\_package命令一起使用而设计的。 因此，使用CMake构建GEANT4应用程序涉及使用此CMake命令和其他CMake命令编写CMakeLists.txt脚本来定位GEANT4并描述客户端应用程序的构建。 虽然编写脚本需要一点努力，但CMake提供了一个非常友好但功能强大的工具，尤其是在您正在多个平台上工作的情况下。 因此，这是我们建议用于构建GEANT4应用程序的方法。

我们将使用基本示例B1，您可以在GEANT4源目录下的examples / basic / B1下找到它，以演示如何使用CMake构建GEANT4应用程序。 你可以在这里找到所有命令的最新CMake文档的链接，所以请按照这些链接获取更多信息。 应用程序源和脚本按以下目录结构进行排列：
\begin{lstlisting}[numbers=none,language=sh]

+- B1/
   +- CMakeLists.txt
   +- exampleB1.cc
   +- include/
   |  ... headers.hh ...
   +- src/
      ... sources.cc ...
\end{lstlisting}

这里，exampleB1.cc包含应用程序的main（），include /和src /分别包含实现类的头文件和源文件。 除了CMakeLists.txt文件在应用程序的根目录中的位置之外，使用CMake构建源文件的这种安排不是必需的。
文本文件CMakeLists.txt是CMake脚本，其中包含描述如何构建exampleB1应用程序的命令
\begin{lstlisting}[language=make]
# (1)
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(B1)

# (2)
option(WITH_GEANT4_UIVIS "Build example with Geant4 UI and Vis drivers" ON)
if(WITH_GEANT4_UIVIS)
  find_package(Geant4 REQUIRED ui_all vis_all)
else()
  find_package(Geant4 REQUIRED)
endif()

# (3)
include(${Geant4_USE_FILE})
include_directories(${PROJECT_SOURCE_DIR}/include)

# (4)
file(GLOB sources ${PROJECT_SOURCE_DIR}/src/*.cc)
file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.hh)

# (5)
add_executable(exampleB1 exampleB1.cc ${sources} ${headers})
target_link_libraries(exampleB1 ${Geant4_LIBRARIES})

# (6)
set(EXAMPLEB1_SCRIPTS
  exampleB1.in
  exampleB1.out
  init_vis.mac
  run1.mac
  run2.mac
  vis.mac
  )

foreach(_script ${EXAMPLEB1_SCRIPTS})
  configure_file(
    ${PROJECT_SOURCE_DIR}/${_script}
    ${PROJECT_BINARY_DIR}/${_script}
    COPYONLY
    )
endforeach()

# (7)
install(TARGETS exampleB1 DESTINATION bin)
\end{lstlisting}

为了清楚起见，上面的清单已经删除了在实际文件中找到的主要注释（CMake注释以“＃”开头），以突出显示每个不同的任务：

1.	Basic Configuration基本设置

cmake\_minimum\_required命令只是确保我们正在使用合适的CMake版本。 虽然GEANT4的构建本身需要CMake 3.3，并且我们为您自己的项目推荐此版本，但Geant4Config.cmake可以支持2.6和2.8系列。 项目命令设置项目的名称并启用和配置C和C ++编译器。.

2.	Find and Configure GEANT4查找并配置GEANT4

前面提到的find\_package命令用于定位和配置GEANT4（稍后我们将在运行CMake时看到如何指定位置），并提供REQUIRED参数，以便CMake在找不到GEANT4时失败并显示错误。 option命令指定了一个默认为ON的布尔变量，当通过-D命令行参数运行CMake时可以设置该变量，或者在CMake GUI界面中切换。 我们将对find\_package的调用封装在选项值的条件块中。 这允许我们通过对find\_package的ui\_all vis\_all“component”参数来配置exampleB1使用GEANT4 UI和Visualization驱动程序。 稍后介绍这些组件及其用法。

3.	Configure the Project to Use GEANT4 and B1 Headers将项目配置为使用GEANT4和B1标题

要自动配置头文件路径，并强制设置编译器标志和编译器定义，以便根据GEANT4进行编译，我们使用include命令加载由GEANT4提供的CMake脚本。 当GEANT4被find\_package定位时，名为Geant4\_USE\_FILE的CMake变量被设置为该模块的路径。 我们使用include\_directories命令将B1头文件目录添加到编译器的头文件搜索路径中。 CMake变量PROJECT\_SOURCE\_DIR指向项目的顶级目录，并且由早先对项目命令的调用设置。

4.	List the Sources to Build the Application列出Sources以构建应用程序

使用file命令的通配功能来准备B1源文件和头文件的列表。

但请注意，CMake globbing仅作为一种便利使用。 glob的扩展只发生在CMake运行时，所以如果以后添加或删除文件，生成的构建脚本将不会知道发生了更改。 Kitware强烈建议显式列出源代码，因为CMake自动使构建依赖于CMakeLists.txt文件。 这意味着如果您明确列出CMakeLists. txt中的源代码，当你重建时，你所做的任何更改都会自动被选中。 当您在使用版本控制源和多个贡献者的项目上工作时，这是非常有用的。


5.	Define and Link the Executable定义和链接可执行文件

add\_executable命令定义应用程序的构建，输出一个由其第一个参数命名的可执行文件，其源代码如下。请注意，我们将标题添加到源列表中，以便它们将出现在Xcode等IDE中。

添加可执行文件后，我们使用target\_link\_libraries命令将其与GEANT4库链接。 Geant4\_LIBRARIES变量在GEANT4所在的位置由find\_package设置，并且是所有需要链接以使用GEANT4的库的列表。.

6.	Copy any Runtime Scripts to the Build Directory复制运行时的脚本到生成目录

因为我们希望支持源代码构建，所以我们不会将CMake生成的文件与我们的实际源码混合在一起，因此我们将B1应用程序使用的任何脚本复制到构建目录。我们使用foreach循环遍历我们构造的脚本列表，并使用configure\_file来执行实际的拷贝。

在这里，CMake变量PROJECT\_BINARY\_DIR由前面对项目命令的调用设置，并指向我们运行CMake来配置构建的目录。.

7.	If Required, Install the Executable如果需要，安装可执行文件

使用install命令创建一个安装目标，它将把可执行文件安装到下面的bin目录下
CMAKE\_INSTALL\_PREFIX。

如果您不打算将您的应用程序安装，即您只想在构建时在本地使用它，则可以将其保留。.


这个命令序列是使用GEANT4编译和链接应用程序的最基本需求，并且可以轻松扩展到更多涉及的用例，如平台特定配置或使用其他第三方软件包（通过find\_package）。

使用CMake脚本，使用它来构建应用程序是一个两步过程。首先运行CMake来生成构建脚本来描述构建。默认情况下，这些将是Unix平台上的Makefiles和Windows上的Visual Studio解决方案，但是如果您愿意，您可以为Xcode和Eclipse等其他工具生成脚本。其次，构建脚本由选定的构建工具运行以编译和链接应用程序【\footnote{译者注{translate by九九之九}：可以使用win7+cmake+vs}】。

CMake的一个关键概念是，我们生成构建脚本【buildscripts】，并在源代码所在的目录（即）中的单独目录（即所谓的build directory）中运行build。这与我们在构建GEANT4时使用的技术完全相同。虽然这看起来很尴尬，但它是一种非常有用的技术。它可以防止CMake生成的文件与应用程序生成的文件混合在一起，并且允许您针对单个源进行多个生成，而无需清理，重新配置和重新生成。

我们将在使用Makefiles的Linux / macOS上以及使用Visual Studio的Windows上说明此配置和构建过程。示例脚本和GEANT4的Geant4Config.cmake脚本是vanilla CMake，所以您应该可以毫无问题地使用其他生成器（例如Xcode和Eclipse）.

\subsubsection{Building ExampleB1 with CMake on Unix with Makefiles}
我们假设，仅用于说明，您已将exampleB1源复制到您home中的目录下，以便我们拥有：:

\begin{lstlisting}[numbers=none,language=sh]
+- /home/you/B1/
   +- CMakeLists.txt
   +- exampleB1.cc
   +- include/
   +- src/
   +- ...
\end{lstlisting}

这里，我们的源代码目录是/ home / you / B1，换句话说就是保存CMakeLists.txt文件的目录。

我们还假设您已经在家中安装了GEANT4，仅用于说明/ home / you / geant4-install。

我们的第一步是创建一个构建目录，在其中构建示例。 我们将与我们的B1源目录一起创建，如下所示：

\begin{lstlisting}[numbers=none,language=sh]
$ cd $HOME
$ mkdir B1-build
\end{lstlisting}

我们现在转到这个构建目录【build directory】并运行CMake来生成构建B1应用程序所需的Makefile。 我们通过CMake两个参数。
\begin{lstlisting}[numbers=none,language=sh]
$ cd $HOME/B1-build
$ cmake -DGeant4_DIR=/home/you/geant4-install/lib64/Geant4-G4VERSION $HOME/B1
\end{lstlisting}

在这里，第一个参数指向我们安装GEANT4的CMake。 具体来说，它是hold GEANT4安装的Geant4Config.cmake文件的目录，以帮助CMake查找并使用GEANT4。 您当然应该将这个变量的值调整到您的实际GEANT4安装的位置。 这提供了将CMake指向要使用的GEANT4安装的最具体方法。 您也可以使用CMAKE\_PREFIX\_PATH变量，例如：
\begin{lstlisting}[numbers=none,language=sh]
$ cd $HOME/B1-build
$ cmake -DCMAKE_PREFIX_PATH=/home/you/geant4-install $HOME/B1
\end{lstlisting}

这对于系统集成商【system integrator】非常有用，因为它可以通过环境或命令行进行扩展，并带有路径到其他所需软件包的安装前缀。

CMake的第二个参数是我们要构建的应用程序的源代码目录的路径。 这里只是前面讨论过的B1目录。 您当然应该将该变量的值调整到您复制B1源目录的位置。

CMake现在将运行来配置构建并生成Makefile，您将看到类似于的输出
\begin{lstlisting}[numbers=none,language=sh]
$ cmake -DGeant4_DIR=/home/you/geant4-install/lib64/Geant4-G4VERSION $HOME/B1
-- The C compiler identification is GNU 4.9.2
-- The CXX compiler identification is GNU 4.9.2
-- Check for working C compiler: /usr/bin/gcc-4.9
-- Check for working C compiler: /usr/bin/gcc-4.9 -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/g++-4.9
-- Check for working CXX compiler: /usr/bin/g++-4.9 -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/you/B1-build
\end{lstlisting}

确切的输出将取决于UNIX变体和编译器，但最后三行应该与所使用的确切路径相同。

如果您现在列出构建目录的内容，则可以看到生成的文件：

\begin{lstlisting}[numbers=none,language=sh]
$ ls
CMakeCache.txt       exampleB1.in   Makefile      vis.mac
CMakeFiles           exampleB1.out  run1.mac
cmake_install.cmake  init_vis.mac   run2.mac
\end{lstlisting}

请注意Makefile，并且运行我们即将构建的exampleB1应用程序的所有脚本都已被复制。 在Makefile可用的情况下，我们现在可以通过简单地运行make来构建：
\begin{lstlisting}[numbers=none,language=sh]
$ make -jN
\end{lstlisting}
CMake生成Makefiles支持并行构建，因此N可以设置为您计算机上的核心数量（例如，在双核处理器上，您可以将N设置为2）。 当make运行时，你应该看到输出：
\begin{lstlisting}[numbers=none,language=sh]
$ make
Scanning dependencies of target exampleB1
[ 16%] Building CXX object CMakeFiles/exampleB1.dir/exampleB1.cc.o
[ 33%] Building CXX object CMakeFiles/exampleB1.dir/src/B1PrimaryGeneratorAction.cc.o
[ 50%] Building CXX object CMakeFiles/exampleB1.dir/src/B1EventAction.cc.o
[ 66%] Building CXX object CMakeFiles/exampleB1.dir/src/B1RunAction.cc.o
[ 83%] Building CXX object CMakeFiles/exampleB1.dir/src/B1DetectorConstruction.cc.o
[100%] Building CXX object CMakeFiles/exampleB1.dir/src/B1SteppingAction.cc.o
Linking CXX executable exampleB1
[100%] Built target exampleB1
\end{lstlisting}

CMake Unix Makefiles非常简洁，但可以通过添加VERBOSE参数使它们变得更加冗长：:
\begin{lstlisting}[numbers=none,language=sh]
$ make VERBOSE=1
\end{lstlisting}

如果您现在列出构建目录的内容，您将看到已创建exampleB1应用程序可执行文件：

\begin{lstlisting}[numbers=none,language=sh]
$ ls
CMakeCache.txt       exampleB1      init_vis.mac      run2.mac
CMakeFiles           exampleB1.in   Makefile          vis.mac
cmake_install.cmake  exampleB1.out  run1.mac
\end{lstlisting}
You can now run the application in place: 您现在可以运行该应用程序：
\begin{lstlisting}[numbers=none,language=sh]
$ ./exampleB1
Available UI session types: [ GAG, tcsh, csh ]

*************************************************************
 Geant4 version Name: geant4-10-04 [MT]   (08-December-2017)
  << in Multi-threaded mode >>
                      Copyright : Geant4 Collaboration
                      Reference : NIM A 506 (2003), 250-303
                            WWW : http://cern.ch/geant4
*************************************************************

<<< Reference Physics List QBBC
Visualization Manager instantiating with verbosity "warnings (3)"...
Visualization Manager initialising...
Registering graphics systems...
\end{lstlisting}

请注意，显示的确切输出将取决于GEANT4和您的应用程序的配置。 进一步的输出和行为超出注册图形系统【Registering graphics systems】...行将取决于您的GEANT4安装支持什么UI和可视化驱动程序。 如果您记得使用find\_package命令中的ui\_all vis\_all，则会导致在应用程序中激活所有可用的UI和可视化驱动程序。 如果你不想要任何UI或可视化，你可以在build目录中用参数重新运行CMake：
\begin{lstlisting}[numbers=none,language=sh]
$ cmake -DWITH_GEANT4_UIVIS=OFF .
\end{lstlisting}
这会将我们设置的选项【option】切换为false，并导致find\_package不为应用程序激活任何UI或可视化。 您可以轻松调整此模式，为您的应用程序提供选项，例如附加组件或功能。

构建完成后，您可以在源目录【source directory】中编辑应用程序的代码。 您只需要在相应的构建目录中重新运行make以获取并编译更改。 但是，请注意，由于使用CMake通配符来创建源文件列表，因此如果添加或删除文件，则必须记住重新运行CMake以获取更改。 这是Kitware建议明确列出来源的另一个原因。
\subsubsection{Building ExampleB1 with CMake on Windows with Visual Studio【使用VS在Win上构建具有CMake的B1】}
与构建GEANT4本身一样，用于在Windows上构建应用程序的最简单系统是Visual Studio开发人员命令提示符，可以从开始→Visual Studio 2017→开发人员命令提示符VS2017（类似于VS2015）

我们假设，仅用于说明，您已将exampleB1源代码复制到目录C：\ Users \ YourUsername \ B1中，那么我们拥有：

\begin{lstlisting}[numbers=none,language=sh]
+- C:\Users\YourUsername\B1
   +- CMakeLists.txt
   +- exampleB1.cc
   +- include\
   +- src\
   +- ...
\end{lstlisting}

在这里，我们的源代码目录是C：\ Users \ YourUsername \ B1，换句话说就是保存CMakeLists.txt文件的目录。
我们还假设您已经在您的home 中安装了GEANT4，仅用于说明，C：\ Users \ YourUsername \ Geant4-install。
我们的第一步是创建一个构建目录【build directory】，在其中构建示例。 我们将按照以下方式与我们的B1源目录一起创建这个目录，从Visual Studio开发人员命令提示符开始工作：
\begin{lstlisting}[numbers=none,language=sh]
> cd %HOMEPATH%
> mkdir B1-build
\end{lstlisting}
我们现在转到这个构建目录并运行CMake来生成构建B1应用程序所需的Visual Studio解决方案。我们通过CMake两个参数
\begin{lstlisting}[numbers=none,language=sh]
> cd %HOMEPATH%\Geant4\B1-build
> cmake -DGeant4_DIR="%HOMEPATH%\Geant4-install\lib\Geant4-G4VERSION" "%HOMEPATH%\B1"
\end{lstlisting}
在这里，第一个参数指向CMake来安装GEANT4。具体来说，它是保存GEANT4安装的Geant4Config.cmake文件的目录，以帮助CMake查找并使用GEANT4。您当然应该将这个变量的值调整到您的实际GEANT4安装的位置。和上面的例子一样，你也可以使用CMAKE\_PREFIX\_PATH变量。第二个参数是我们要构建的应用程序的源代码目录的路径。这里只是前面讨论过的B1目录。当然，您应该将其调整到您复制B1源目录的位置。在两种情况下，在包含空格的路径的情况下引用参数。

CMake现在将运行来配置构建并生成Visual Studio解决方案，您将看到类似于的输出
\begin{lstlisting}[numbers=none,language=sh]
-- Building for: Visual Studio 15 2017
-- The C compiler identification is MSVC 19.11.25547.0
-- The CXX compiler identification is MSVC 19.11.25547.0
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x86/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x86/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x86/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.11.25503/bin/Hostx86/x86/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/YourUsername/B1-build
\end{lstlisting}
如果您现在列出构建目录的内容，则可以看到生成的文件：
\begin{lstlisting}[numbers=none,language=sh]
> dir /B
ALL_BUILD.vcxproj
ALL_BUILD.vcxproj.filters
B1.sln
B1.vcxproj
B1.vcxproj.filters
CMakeCache.txt
CMakeFiles
cmake_install.cmake
exampleB1.in
exampleB1.out
exampleB1.vcxproj
exampleB1.vcxproj.filters
init_vis.mac
INSTALL.vcxproj
INSTALL.vcxproj.filters
run1.mac
run2.mac
vis.mac
ZERO_CHECK.vcxproj
ZERO_CHECK.vcxproj.filters
\end{lstlisting}
请注意B1.sln解决方案文件，并且运行我们即将构建的exampleB1应用程序的所有脚本都已被复制。 有了解决方案，我们现在可以通过运行cmake来驱动MSBuild来构建：
\begin{lstlisting}[numbers=none,language=sh]
> cmake --build . --config Release
\end{lstlisting}
基于解决方案的版本非常冗长，但最终不应该看到任何错误。 在上面，我们已经在Release模式下构建了B1程序，这意味着它已经过优化并且没有调试符号。 与building GEANT4本身一样，选择此选项可提供最佳性能。 如果您的应用程序需要调试信息，只需将参数更改为RelWithDebInfo。 请注意，在这两种情况下，您都必须使应用程序的配置与GEANT4安装的配置相匹配，即如果您正在以发布模式构建应用程序，则确保它使用的是GEANT4的发布版本。 如果使用混合配置，则可能会导致链接和/或运行时错误。

在运行构建之后，如果我们再次列出构建目录的内容，我们会看到：
\begin{lstlisting}[numbers=none,language=sh]
> dir /B
ALL_BUILD.vcxproj
ALL_BUILD.vcxproj.filters
B1.sln
B1.vcxproj
B1.vcxproj.filters
CMakeCache.txt
CMakeFiles
cmake_install.cmake
exampleB1.dir
exampleB1.in
exampleB1.out
exampleB1.vcxproj
exampleB1.vcxproj.filters
init_vis.mac
INSTALL.vcxproj
INSTALL.vcxproj.filters
Release
run1.mac
run2.mac
vis.mac
Win32
ZERO_CHECK.vcxproj
ZERO_CHECK.vcxproj.filters

> dir /B Release
exampleB1.exe
...
\end{lstlisting}
这里，Release子目录包含可执行文件，主build目录包含用于运行该程序的所有.mac脚本。 如果以不同的模式构建，那么该模式的可执行文件将位于为该模式命名的目录中，例如，RelWithDebInfo/ exampleB1.exe。 您现在可以运行该应用程序：
\begin{lstlisting}[numbers=none,language=sh]
> .\Release\exampleB1.exe

*************************************************************
 Geant4 version Name: geant4-10-04    (08-December-2017)
                      Copyright : Geant4 Collaboration
                      Reference : NIM A 506 (2003), 250-303
                            WWW : http://cern.ch/geant4
*************************************************************

<<< Reference Physics List QBBC
Visualization Manager instantiating with verbosity "warnings (3)"...
Visualization Manager initialising...
Registering graphics systems...
\end{lstlisting}
请注意，显示的确切输出将取决于GEANT4和您的应用程序的配置。 进一步的输出和行为超出注册图形系统【Registering graphics systems】...行将取决于您的GEANT4安装支持什么UI和可视化驱动程序。

虽然Visual Studio Developer Command提示提供了构建应用程序的最简单方法，但也可以直接在Visual Studio IDE中打开生成的Visual Studio Solution文件（上例中的B1.sln）。 这提供了一个更全面的开发和调试环境，如果你想使用它，你应该查阅它的文档。

一个关键的CMake相关项目可以返回到我们在add\_executable调用中的应用程序头部列表。 虽然CMake自然会忽略这些配置应用程序的编译，但它会将它们添加到Visual Studio解决方案中。 如果不列出它们，它们将不能在Visual Studio IDE的解决方案中编辑。

\subsection{Using Geant4Make to build Applications【使用Geant4Make构建应用程序】}
